class MyWishListsController < ApplicationController

  #control general de acceso cancan, segun los permisos definidos en ability.rb
  authorize_resource :resource => :my_wish_lists

  def redirect_back
      redirect_back_or_default params[:url]
  end

  def show_material_details
    # recibe por parametro el material_wish_list.id
    @material_wish_list = MaterialsWishList.find(params[:materials_wish_list_id])

    # seteo a que lista tiene que volver
    session[:special_return_to_controller] = "my_wish_lists"
    session[:special_return_to_code] = @material_wish_list.wish_list.id

    #redirijo al show de materials
    redirect_to material_path(@material_wish_list.material)
  end

  def special_return_to
    if session[:special_return_to_code].nil?
      session[:wish_list_selected] = nil
      redirect_to :action => :index
    else
      # obtengo el material_wish_list segun la calve que habia guardado antes
      @wish_list = WishList.find(session[:special_return_to_code].to_i)

      session[:special_return_to_controller] = nil
      session[:special_return_to_code] = nil

      if @wish_list.type_list == WishList::TYPE_CART
        redirect_to :my_cart
      end
      if @wish_list.type_list == WishList::TYPE_FAVORITE
        redirect_to :my_favorites
      end
      if @wish_list.type_list == WishList::TYPE_RESERVE
        redirect_to :my_reservations
      end
      if @wish_list.type_list == WishList::TYPE_SIMPLE
        session[:wish_list_selected] = @wish_list.id
        redirect_to :action => :index
      end
    end
  end

  def redirect_back
    redirect_back_or_default params[:url]
  end

  def index_init
    session[:wish_list_selected] = nil
    session[:search_material_title] = nil
    redirect_to :action => :index
  end

  def index
    save_redirect_back request.request_uri
    @search_wish_lists = load_wish_lists_user
    @materials_wish_lists = load_materials_wish_lists params
  end

  def observer_wish_list_selected_search
    session[:wish_list_selected] = params[:wish_list_selected]
    @materials_wish_lists = load_materials_wish_lists params
    render :partial=> "wish_list_materials" , :layout=>false
  end

  def observer_materials_search
    session[:search_material_title] = params[:search_material_title]
    @materials_wish_lists = load_materials_wish_lists params
    render :partial=> "wish_list_materials" , :layout=>false
  end

  def paginate_wish_list_materials
    @materials_wish_lists = load_materials_wish_lists params
  end

  def new
    @wish_list = WishList.new
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @wish_list }
    end
  end

  def edit
    if session[:wish_list_selected].nil? || session[:wish_list_selected] == "-1"
#        flash[:alert] = t('my_wish_list_select_list')
        redirect_to :action => :index
    else
      @wish_list = WishList.find(session[:wish_list_selected])
      check_access @wish_list
    end
  end

  def create
    @wish_list = WishList.new(params[:wish_list])
    @wish_list.user = current_user
    @wish_list.type_list = WishList::TYPE_SIMPLE

    if @wish_list.save
#        flash[:notice] = t('msg_record_successfully_created')
      session[:wish_list_selected]= @wish_list.id
      session[:search_material_title] = nil
      redirect_to :action => :index
    else
      render :action => :new
    end
  end

  def update
    @wish_list = WishList.find(params[:id])
    if check_access @wish_list
      if @wish_list.update_attributes(params[:wish_list])
#        flash[:notice] = t('msg_record_successfully_updated')
        redirect_to :action => :index
      else
        render :action => :edit
      end
    end
  end

  def destroy
    if session[:wish_list_selected].nil? || session[:wish_list_selected] == "-1"
#        flash[:alert] = t('my_wish_list_select_list')
        redirect_to :action => :index
    else
      @wish_list = WishList.find(session[:wish_list_selected])
      if check_access @wish_list
        @wish_list.destroy
#        flash[:notice] = t('msg_record_successfully_destroy')
        session[:wish_list_selected]= nil
        session[:search_material_title] = nil
        redirect_to :action => :index
      end
    end
  end

  def up_material
    #se busca el registro asociado a esta lista-material
    wish_list_material = MaterialsWishList.find(params[:materials_wish_list_id])

    #busco el primer material con order < al registro elegido
    wish_list_material_prev = MaterialsWishList.find(:first,:order => "order_list DESC", :conditions => ["wish_list_id = ? and order_list < ?", wish_list_material.wish_list_id, wish_list_material.order_list])

    if !wish_list_material_prev.nil?
      #swap
      temp = wish_list_material.order_list
      wish_list_material.order_list = wish_list_material_prev.order_list
      wish_list_material_prev.order_list = temp
      #save
      wish_list_material.save
      wish_list_material_prev.save
    end

    @materials_wish_lists = load_materials_wish_lists params
    render :partial=> "wish_list_materials" , :layout=>false
  end

  def down_material
    #se busca el registro asociado a esta lista-material
    wish_list_material = MaterialsWishList.find(params[:materials_wish_list_id])

    #busco el primer material con order > al registro elegido
    wish_list_material_next = MaterialsWishList.find(:first,:order => "order_list", :conditions => ["wish_list_id = ? and order_list > ?", wish_list_material.wish_list_id, wish_list_material.order_list])

    if !wish_list_material_next.nil?
      #swap
      temp = wish_list_material.order_list
      wish_list_material.order_list = wish_list_material_next.order_list
      wish_list_material_next.order_list = temp
      #save
      wish_list_material.save
      wish_list_material_next.save
    end

    @materials_wish_lists = load_materials_wish_lists params
    render :partial=> "wish_list_materials" , :layout=>false
  end

  def delete_material
    #se busca el registro asociado a esta lista-material
    wish_list_material = MaterialsWishList.find(params[:materials_wish_list_id])
    wish_list_material.destroy
    @materials_wish_lists = load_materials_wish_lists params
    render :partial=> "wish_list_materials" , :layout=>false
  end

  def my_favorites
    session[:return_to_catalog] = false
    save_redirect_back request.request_uri
    show_especial_wish_list WishList::TYPE_FAVORITE, params
  end

  def my_reservations
    if session[:caller_from_special_list] == true
      session[:caller_from_special_list] == false
    else
      session[:return_to_catalog] = false
    end
    
    save_redirect_back request.request_uri
    show_especial_wish_list WishList::TYPE_RESERVE, params
  end

  def my_cart
    if session[:caller_from_special_list] == true
      session[:caller_from_special_list] == false
    else
      session[:return_to_catalog] = false
    end
    save_redirect_back request.request_uri
    show_especial_wish_list WishList::TYPE_CART, params
  end


  def delete_materials
    str_ids = params[:material_wish_lists_selected] || []
    ids = str_ids.map { |id| id.to_i }
    if ids.length > 0
      MaterialsWishList.delete(ids)
      if ids.length == 1
        flash_message :notice, t('msg_record_successfully_deleted')
      else
        flash_message :notice, t('msg_records_successfully_deleted')
      end
    else
      flash_message :alert, t('lbl_must_select_materials')
    end

    @materials_wish_lists = load_materials_wish_lists params

    if @materials_wish_lists.length == 0
      flash[:notice] = nil
    end

    render :partial=> "wish_list_materials" , :layout=>false
  end

  def process_cart
    #TODO: falta procesar el carro
    @materials_wish_lists = load_materials_wish_lists params
    render :partial=> "wish_list_materials" , :layout=>false
  end

  def process_reserve
    #TODO: falta procesar las reservas
    @materials_wish_lists = load_materials_wish_lists params
    render :partial=> "wish_list_materials" , :layout=>false
  end

  def define_materials_to_cart_from_catalog
      str_ids = session[:materials_id_to_add_cart] || []
      ids = str_ids.map { |id| id.to_i }
      session[:materials_id_to_add_cart] = nil

      @type_item_list = "Material"
      @special_list = WishList::TYPE_CART
      @materials = Material.find(ids, :order => "title")

      session[:special_return_to_controller] = "catalogs"
      session[:special_return_to_code] = nil
      render "define_materials_to_special_list"
  end

  def define_materials_to_cart_from_material_details
      id = session[:material_selected].to_i
      session[:material_selected] = nil

      @type_item_list = "Material"
      @special_list = WishList::TYPE_CART
      @materials = Material.find(:all, :conditions => "id = #{id}", :order => "title")

      render "define_materials_to_special_list"
  end

  def define_materials_to_reservations_from_catalog
      #TODO: aca tengo que recibir una array de material_id y tengo que cargar en @materials las instancias de esos materiales
      ids = [6,5,4,3,2,1]

      @type_item_list = "Material"
      @special_list = WishList::TYPE_RESERVE
      @materials = Material.find(ids, :order => "title")

      session[:special_return_to_controller] = "catalogs"
      session[:special_return_to_code] = nil
      render "define_materials_to_special_list"
  end

  def define_materials_to_special_list_from_wish_list
      str_ids = params[:material_wish_lists_selected] || []
      ids = str_ids.map { |id| id.to_i }
      @type_item_list = "MaterialsWishList"
      @materials_wish_lists = MaterialsWishList.find(ids, :include => [:material, :wish_list], :order => "wish_lists.name, materials.title")

      if !params["define_materials_to_cart"].nil?
        @special_list = WishList::TYPE_CART
      end
      if !params["define_materials_to_reserve"].nil?
        @special_list = WishList::TYPE_RESERVE
      end

      session[:special_return_to_controller] = "my_wish_lists"
      if @materials_wish_lists.length > 0
        session[:special_return_to_code] = @materials_wish_lists[0].wish_list.id
        render "define_materials_to_special_list"
      else
        session[:special_return_to_code] = nil
        flash_message :alert, t('lbl_must_select_materials')
        redirect_back  
      end
      
  end

  def add_materials_to_special_list
    materials_ids = []
    materials_counts = []

    if params[:type_item_list] == "MaterialsWishList"
      remove_materials_from_list = params[:remove_materials_from_wish_lists] == "yes"
      str_ids = params[:material_wish_lists_selected] || []
      str_counts = params[:material_wish_lists_selected_count] || []
      str_ids.each_index  do |i|
        materials_wish_list = MaterialsWishList.find(str_ids[i].to_i)
        materials_ids << materials_wish_list.material_id
        materials_counts << str_counts[i].to_i
        if remove_materials_from_list
          MaterialsWishList.delete(str_ids[i].to_i)
        end
      end
    end

    if params[:type_item_list] == "Material"
      str_ids = params[:materials_selected] || []
      str_counts = params[:materials_selected_count] || []
      materials_ids = str_ids.map { |id| id.to_i }
      materials_counts = str_counts.map { |id| id.to_i }
    end

    process_add_materials_to_special_list params[:special_list], materials_ids, materials_counts
    session[:caller_from_special_list] = true
    if params[:special_list] == WishList::TYPE_CART
      redirect_to :action => :my_cart
    end
    if params[:special_list] == WishList::TYPE_RESERVE
      redirect_to :action => :my_reservations
    end
  end

  def edit_material_wish_list
    @material_wish_list = MaterialsWishList.find(params[:materials_wish_list_id])
  end

  def update_material_wish_list
    @material_wish_list = MaterialsWishList.find(params[:materials_wish_list_id])
    @material_wish_list.count = params[:count].to_i || 0
    @material_wish_list.save
    redirect_back
  end

  private

  def process_add_materials_to_special_list type_list, materials_ids, materials_counts
    #se busca el carro de compras del usuario
    special_list = WishList.find(:first, :conditions => ["user_id = ? and type_list = ?", current_user, type_list])

    materials_ids.each_index  do |i|
      #se verifica si ya existe el material en el carro
      material_special_list = MaterialsWishList.find(:first, :conditions => ["wish_list_id = ? and material_id = ?", special_list.id, materials_ids[i]])

      if material_special_list.nil?
        #hay que definir el material en el carro de compras
        MaterialsWishList.create(:wish_list_id => special_list.id, :material_id => materials_ids[i], :count => materials_counts[i], :order_list => 1)
      else
        #se actualiza la cantidad del material
        if material_special_list.count.nil?
          material_special_list.count = 0
        end
        material_special_list.count += materials_counts[i]
        material_special_list.save
      end
    end
  end

  def check_access wish_list
    if !(current_user.role?(:role_admin)) and current_user.id != wish_list.user_id
      show_page_access_denied
      return false
    else
      return true
    end
  end

  def load_materials_wish_lists params
    user_wish_list_ids = []
    paginate_result = true

    if session[:wish_list_selected].nil? || session[:wish_list_selected] == "-1"
      #significa que tengo que pasarle todas las listas del usuario (tipo Simple)
      user_wish_lists = WishList.search(current_user.id, nil, nil, WishList::TYPE_SIMPLE, nil)
      user_wish_lists.each do |wish_list|
        user_wish_list_ids << wish_list.id
      end
    else
      wish_list_id = session[:wish_list_selected].to_i
      user_wish_list_ids << wish_list_id

      #se que eligio una, averiguo si es un carrito o reservas porque no quiero paginar
      wish_list = WishList.find(wish_list_id)
      if (!wish_list.nil?) && (wish_list.type_list == WishList::TYPE_CART || wish_list.type_list == WishList::TYPE_RESERVE)
        paginate_result = false
      end
    end
    if paginate_result
      return MaterialsWishList.search(user_wish_list_ids, session[:search_material_title], params[:page])
    else
      return MaterialsWishList.search_with_paginate(user_wish_list_ids, session[:search_material_title])
    end
  end

  def load_wish_lists_user
    types_list = []
    types_list.replace WishList::LIST_TYPES
    types_list.delete(WishList::TYPE_CART)
    types_list.delete(WishList::TYPE_FAVORITE)
    types_list.delete(WishList::TYPE_RESERVE)
    wish_lists = WishList.search(current_user.id, nil, nil, types_list, nil)
    return [[t("lbl_all_f"), -1]] + wish_lists.map {|u| [u.name,u.id]}
  end

  def show_especial_wish_list(type_list, params)
    session[:search_material_title] = nil
    @wish_list = WishList.find(:first, :conditions => ["user_id = ? and type_list = ?", current_user.id, type_list])
    if @wish_list.nil?
      @wish_list = WishList.create(:user => current_user, :name => type_list, :type_list => type_list)
    end
    session[:wish_list_selected] = @wish_list.id
    @materials_wish_lists = load_materials_wish_lists params
    render "index_wish_list"
  end
end
